<template>
  <div
    class="app-container uni-scroll"
    style="height: calc(100vh - 100px)"
  >
    <!--    <el-alert-->
    <!--      v-show="!loading"-->
    <!--      :title="'websocket '+$t('OFFLINE')"-->
    <!--      type="error"-->
    <!--      :close-text="$t('confirm')"-->
    <!--      @close="initSocket"-->
    <!--    />-->
    <span style="margin-left: 13px;color: #34bfa3;">{{ formatSensorType() }}{{ $t('port') }}:{{ port }}</span>
    <span style="margin-left: 13px;" class="text-gray-400">{{ sensorName }}</span>

    <el-row
      id="canvasList"
      :gutter="5"
    >
      <el-col
        v-for="(item,index) in canvasList"
        :key="index"
        :span="item.zooMax ? 24 : 12"
        style="margin-top: 13px"
      >
        <template v-if="item.type === 'line' && (showSort || showHidden === '1' || !item.hidden)">
          <div :class="['item', {'sort-border':showSort}]" style="padding:5px;margin-bottom: 5px">
            <div style="margin: 0 20px;display: flex;justify-content: space-between">
              <div style="display: flex">
                <device-explain-icon :explain="item" style="margin: 2px"/>
                <div style="flex-grow: 1;margin-left: 5px">
                  <div style="font-size:13px;font-weight: lighter;">
                    <span class="primary-color">
                      <el-popover
                        v-if="item.remark && item.remark!==''"
                        placement="top"
                        width="200"
                        trigger="hover"
                        :content="item.name"
                      >
                        <span slot="reference">{{ item.remark }}</span>
                      </el-popover>
                      <span v-else>{{ item.name }}</span>
                    </span>
                    <span style="float: right;color: #909399;">{{
                        (enableEval === '1' ? item.value : item.rawValue)
                      }}<span style="font-size:12px">{{ item.unit }}</span></span>
                    <i
                      v-if="enableEval === '1' && item.value != '' && !isNaN(Number(item.value)) && item.lastValue != '' && !isNaN(Number(item.lastValue))"
                      :class="item.value > item.lastValue ? 'el-icon-top':'el-icon-bottom'"
                    />
                    <i
                      v-else-if="item.value != '' && !isNaN(Number(item.value)) && item.lastValue != '' && !isNaN(Number(item.lastValue))"
                      :class="item.rawValue > item.lastRawValue ? 'el-icon-top':'el-icon-bottom'"
                    />
                  </div>
                  <div style="font-size:12px;color: #909399;margin-top: 2px">{{ formatDate(item.valueDate) }}</div>
                </div>
              </div>
              <el-button-group>
                <el-button
                  :type="item.warnNum > 0 ? 'danger':''"
                  icon="el-icon-more"
                  @click="explainInfo(item)"
                />
                <el-button
                  v-if="!item.zooMax"
                  icon="el-icon-full-screen"
                  @click="zooMax(item)"
                />
                <el-button
                  v-else
                  icon="el-icon-crop"
                  @click="zooMin(item)"
                />
                <el-button
                  v-if="showSort && !item.hidden"
                  type="danger"
                  icon="el-icon-close"
                  @click="hiddenExplain(item)"
                />
                <el-button
                  v-else-if="showSort"
                  icon="el-icon-view"
                  @click="showExplain(item)"
                />
              </el-button-group>
            </div>
            <line-chart :chart-data="item" style="width: 100%;height: 330px"/>
          </div>
        </template>
        <template v-else>
          <div :class="['item', {'sort-border':showSort}]" style="padding-top: 8px;margin-bottom: 5px">
            <el-table
              :data="item.data"
              style="width: 94%;margin: 0 auto"
              height="325"
            >
              <el-table-column prop="value">
                <template slot="header" slot-scope="scope">
                  <el-popover
                    v-if="item.remark && item.remark!==''"
                    placement="top"
                    width="200"
                    trigger="hover"
                    :content="item.name"
                  >
                    <span slot="reference">{{ item.remark }}</span>
                  </el-popover>
                  <span v-else>{{ item.name }}</span>
                </template>
              </el-table-column>
              <el-table-column prop="date"/>
            </el-table>
          </div>
        </template>
      </el-col>
    </el-row>
    <div style="margin-top: 13px;margin-left: 25px">
      <el-button-group style=";margin-right: 5px">
        <el-button
          round
          icon="el-icon-date"
          type="primary"
          @click="gotoHistory"
        >{{ $t('history') }}
        </el-button>
        <el-button
          icon="el-icon-rank"
          type="primary"
          @click="showSort=!showSort"
        >{{ $t('rank') }}
        </el-button>
        <el-button
          round
          icon="el-icon-news"
          type="primary"
          @click="openNew"
        >{{ $t('new') + $t('window') }}
        </el-button>
      </el-button-group>
      <el-switch
        v-model="enableEval"
        active-value="1"
        inactive-value="0"
        :active-text="$t('enable')+$t('script')"
        @change="enableEvalChange"
      />
      <el-switch
        v-model="showHidden"
        active-value="1"
        inactive-value="0"
        :active-text="$t('show') +$t('hidden')"
        @change="showHiddenChange"
      />
      <el-switch
        v-model="addFrame"
        active-value="1"
        inactive-value="0"
        :active-text="$t('add')+$t('frame')"
        @change="addFrameChange"
      />
    </div>

    <el-button
      icon="el-icon-setting"
      circle
      type="primary"
      style="position: fixed;bottom: 25px;right: 13px;"
      @click="deviceSetting"
    />

    <el-dialog
      :visible.sync="dialogExplainInfoFormVisible"
      width="1300px"
      top="50px"
    >
      <device-explain-info v-if="dialogExplainInfoFormVisible" :explain="explain"/>
    </el-dialog>

    <el-dialog
      :visible.sync="showSetting"
      :title="deviceName"
      width="1200px"
      top="15px"
    >
      <device-setting
        :sensor-id="sensorId"
        :device-core="deviceCore"
        class="uni-scroll"
        style="height: 600px"
      />
    </el-dialog>

  </div>
</template>

<script>
import { failureNotice, formatDate, formatSensorType } from '@/util/common'
import { getAddFrame, getEnableEval, getShowHidden, setAddFrame, setEnableEval, setShowHidden } from '@/util/storage'
import { listExplain, updateExplain, updateExplainList } from '@/api/iot/iotDeviceExplainApi'
import DeviceSetting from '@/components/DeviceSetting/index'
import Sortable from 'sortablejs'
import LineChart from '@/components/Chart/LineChart'
import resize from '@/components/Mixins/resize'
import DeviceExplainInfo from '@/components/DeviceExplainInfo'
import DeviceExplainIcon from '@/components/DeviceExplainIcon'
import { leaveWebSocket, listenWebSocket } from '@/util/websocketTool'

export default {
  name: 'SensorRealTime',
  components: {
    LineChart,
    DeviceSetting,
    DeviceExplainInfo,
    DeviceExplainIcon
  },
  mixins: [resize],
  data() {
    return {
      canvasList: [],
      dialogExplainInfoFormVisible: false,
      // loading: false,
      showSort: false,
      sensorId: null,
      deviceCore: null,
      sensorName: null,
      port: null,
      type: null,
      deviceName: null,
      showSetting: false,
      explainList: [],
      explain: {},
      rankExplainList: [],
      // ws: null,
      enableEval: getEnableEval(),
      showHidden: getShowHidden(),
      addFrame: getAddFrame(),
      wsMonitor: {
        room: 'iot:device:' + this.deviceCore,
        onmessage: this.onSocketMsg
      }
    }
  },
  beforeDestroy() {
    this.closeSocket()
  },
  mounted() {
    const param = this.$route.query
    this.sensorId = param.sensorId ? parseInt(param.sensorId) : null
    this.deviceCore = param.deviceCore
    this.port = param.port
    this.type = parseInt(param.type)
    this.deviceName = param.deviceName
    this.sensorName = param.sensorName
    this.listExplain()
    this.setTagsViewTitle()
    this.wsMonitor.room = 'iot:device:' + this.deviceCore
    listenWebSocket(this.wsMonitor)
  },
  methods: {
    gotoHistory() {
      this.$router.push({
        path: '/device/sensor/history/' + this.sensorId,
        query: {
          port: this.port,
          type: this.type,
          sensorId: this.sensorId,
          deviceName: this.deviceName,
          deviceCore: this.deviceCore,
          sensorName: this.sensorName
        }
      })
    },
    enableEvalChange() {
      setEnableEval(this.enableEval)
    },
    showHiddenChange() {
      setShowHidden(this.showHidden)
    },
    addFrameChange() {
      setAddFrame(this.addFrame)
    },
    zooMax(item) {
      const type = item.type
      item.type = 'hidden'
      this.$nextTick(() => {
        item.type = type
        item.zooMax = true
      })
    },
    zooMin(item) {
      const type = item.type
      item.type = 'hidden'
      this.$nextTick(() => {
        item.type = type
        item.zooMax = false
      })
    },
    hiddenExplain(item) {
      const hidden = true
      const json = {
        hidden: hidden,
        explainId: item.explainId
      }
      updateExplain(json).then(res => {
        const { code } = res
        if (code === '200') {
          item.hidden = hidden
        }
      })
    },
    showExplain(item) {
      const hidden = false
      updateExplain({
        explainId: item.explainId,
        hidden: hidden
      }).then(res => {
        const { code } = res
        if (code === '200') {
          item.hidden = hidden
        }
      })
    },
    explainInfo(index) {
      this.explain = index
      this.dialogExplainInfoFormVisible = true
    },
    formatDate(time) {
      return formatDate(this, time)
    },
    formatSensorType() {
      return formatSensorType(this, parseInt(this.type))
    },
    closeSocket() {
      // this.loading = false
      leaveWebSocket(this.wsMonitor)
    },
    onSocketMsg(nowData) {
      if (nowData.type === 'deviceData') {
        const data = JSON.parse(nowData.msg)
        if (data.deviceUpload) {
          if (data.deviceUpload.sensorList && data.deviceUpload.sensorList.length > 0) {
            data.deviceUpload.sensorList.forEach(sensor => {
              if (sensor.port === this.port && sensor.explainList && sensor.explainList.length > 0) {

                for (let i = 0, j = this.canvasList.length; i < j; i++) {
                  const canvas = this.canvasList[i]
                  let have = false
                  sensor.explainList.forEach(explain => {
                    if (explain.keyName === canvas.keyName) {
                      if (canvas.type === 'line') {
                        if (canvas.dataList.length >= 60) {
                          canvas.dataList.splice(0, 1)
                          canvas.dateList.splice(0, 1)
                        }
                        canvas.dataList.push(this.enableEval === '1' ? explain.value : explain.rawValue)
                        canvas.dateList.push(this.formatDate(nowData.timestamp))
                      } else {
                        if (canvas.data.length >= 60) {
                          canvas.data.splice(0, 1)
                        }
                        canvas.data.push({
                          value: this.enableEval === '1' ? explain.value : explain.rawValue,
                          date: this.formatDate(nowData.timestamp)
                        })
                      }
                      canvas.lastValue = canvas.value
                      canvas.lastRawValue = canvas.lastValue
                      canvas.value = explain.value
                      canvas.rawValue = explain.rawValue
                      canvas.valueDate = nowData.timestamp
                      this.canvasList.splice(i, 1, canvas)
                      this.have = true
                    }
                  })
                  if (!have && this.addFrame === '1') {
                    if (canvas.type === 'line') {
                      if (canvas.dataList.length >= 60) {
                        canvas.dataList.splice(0, 1)
                        canvas.dateList.splice(0, 1)
                      }
                      canvas.dataList.push(this.enableEval === '1' ? canvas.value : canvas.rawValue)
                      canvas.dateList.push(this.formatDate(nowData.timestamp))
                    } else {
                      if (canvas.data.length >= 60) {
                        canvas.data.splice(0, 1)
                      }
                      canvas.data.push({
                        value: this.enableEval === '1' ? canvas.value : canvas.rawValue,
                        date: this.formatDate(nowData.timestamp)
                      })
                    }
                    canvas.valueDate = nowData.timestamp
                  }
                }
              }
            })
          }
        }
      }
    },
    // initSocket() {
    //   const that = this
    //   this.closeSocket()
    //   this.ws = newWebSocket()
    //   this.ws.onopen = () => {
    //     that.loading = true
    //     that.ws.send(JSON.stringify({
    //       cmd: 'bindRoom',
    //       param: 'iot:device:' + that.deviceCore
    //     }))
    //   }
    //   this.ws.onerror = function(e) {
    //     that.loading = false
    //     console.error('WebSocket is error' + e.code + ' ' + e.reason + ' ' + e.wasClean)
    //     that.closeSocket()
    //     setTimeout(function() {
    //       that.initSocket()
    //     }, 20000)
    //   }
    //   this.ws.onclose = function(e) {
    //     that.loading = false
    //     console.error('WebSocket is close' + e.code + ' ' + e.reason + ' ' + e.wasClean)
    //     that.closeSocket()
    //     setTimeout(function() {
    //       that.initSocket()
    //     }, 20000)
    //   }
    //   this.ws.onmessage = function(msg) {
    //     const nowData = JSON.parse(msg.data)
    //     if (nowData.type === 'deviceData') {
    //       const data = JSON.parse(nowData.msg)
    //       if (data.deviceUpload) {
    //         if (data.deviceUpload.sensorList && data.deviceUpload.sensorList.length > 0) {
    //           data.deviceUpload.sensorList.forEach(sensor => {
    //             if (sensor.port === that.port && sensor.explainList && sensor.explainList.length > 0) {
    //               sensor.explainList.forEach(explain => {
    //                 for (let i = 0, j = that.canvasList.length; i < j; i++) {
    //                   const canvas = that.canvasList[i]
    //                   if (explain.keyName === canvas.keyName) {
    //                     if (canvas.type === 'line') {
    //                       if (canvas.dataList.length >= 60) {
    //                         canvas.dataList.splice(0, 1)
    //                         canvas.dateList.splice(0, 1)
    //                       }
    //                       canvas.dataList.push(that.enableEval === '1' ? explain.value : explain.rawValue)
    //                       canvas.dateList.push(that.formatDate(nowData.timestamp))
    //                     } else {
    //                       if (canvas.data.length >= 60) {
    //                         canvas.data.splice(0, 1)
    //                       }
    //                       canvas.data.push({
    //                         value: that.enableEval === '1' ? explain.value : explain.rawValue,
    //                         date: that.formatDate(nowData.timestamp)
    //                       })
    //                     }
    //                     canvas.lastValue = canvas.value
    //                     canvas.lastRawValue = canvas.lastValue
    //                     canvas.value = explain.value
    //                     canvas.rawValue = explain.rawValue
    //                     canvas.valueDate = nowData.timestamp
    //                     that.canvasList.splice(i, 1, canvas)
    //                   }
    //                 }
    //               })
    //             }
    //           })
    //         }
    //       }
    //     }
    //   }
    // },
    setSortable() {
      const $ul = document.getElementById('canvasList')
      new Sortable($ul, {
        setData(dataTransfer) {
          dataTransfer.setData('Text', '')
        },
        onEnd: evt => {
          const targetRow = this.rankExplainList.splice(evt.oldIndex, 1)[0]
          this.rankExplainList.splice(evt.newIndex, 0, targetRow)
          if (this.showSort) {
            const explainList = []
            for (let i = 0, j = this.rankExplainList.length; i < j; i++) {
              const data = {
                rankNumber: i,
                explainId: this.rankExplainList[i].explainId
              }
              explainList.push(data)
            }
            updateExplainList({
              explainList: explainList
            })
          }
        },
        animation: 150
      })
    },
    openNew() {
      window.open('#/device/sensor/real-time2/' + this.sensorId + '?deviceCore=' + this.deviceCore + '&sensorId=' + this.sensorId + '&sensorName=' + this.sensorName + '&deviceName=' + this.deviceName + '&port=' + this.port + '&type=' + this.type)
    },
    setTagsViewTitle() {
      this.tempRoute = Object.assign({}, this.$route)
      const route = Object.assign({}, this.tempRoute, {
        title: `${this.deviceName}`
      })
      this.$store.dispatch('tagsView/updateVisitedView', route)
    },
    listExplain() {
      listExplain({
        sensorId: this.sensorId
      }).then(res => {
        const { code, data } = res
        if (code === '200') {
          this.showChart(data)
        }
      })
    },
    deviceSetting() {
      this.showSetting = true
    },
    showChart(data) {
      if (data != null && data.length > 0) {
        this.explainList = data
      } else {
        failureNotice(this, this.$t('not') + this.$t('explain'))
        return
      }
      const canvasList = []
      for (let i = 0, j = this.explainList.length; i < j; i++) {
        const explain = this.explainList[i]
        canvasList.push({
          ...explain,
          zooMax: false,
          index: i,
          dataList: [explain.value],
          dateList: [formatDate(this, explain.valueDate)],
          data: [{
            value: explain.value,
            date: formatDate(this, explain.valueDate)
          }]
        })
      }
      this.canvasList = canvasList
      this.setSortable()
    }
  }
}
</script>
<style scoped>
.sort-border {
  border-style: dashed;
  border-color: #6E6F71;
  border-width: 1px;
  border-radius: 12px;
}

.item {
  padding-top: 8px;
  margin-bottom: 5px;
  height: 370px;
}

.item:hover {
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
  border-radius: 12px;
}
</style>
